home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-19 | 9.0 KB | 269 lines | [TEXT/MMCC] |
- /************************************************************************/
- /* Project...: Standard C++ Library */
- /* Name......: CPlusLib.c */
- /* Purpose...: C++ specific runtime functions */
- /* Copyright.: ©Copyright 1993-95 by metrowerks inc */
- /************************************************************************/
-
- #include <stdlib.h>
- #include <CPlusLib.h>
-
- long __ptmf_null[3]; // a NULL pointer to member
-
- /************************************************************************/
- /* Purpose..: Test if a pointer to function member is != 0 */
- /* Input....: pointer to function member */
- /* Return...: 0: is zero; 1: is not zero */
- /************************************************************************/
- asm long __ptmf_test(const PTMF *ptmf)
- {
- move.l 4(sp),a0 // ptr_to_function_member
- tst.l (a0)+ // test if *ptr_to_function_member == { 0L,0L,0L }
- bne.s L9
- tst.l (a0)+
- bne.s L9
- tst.l (a0)+
- bne.s L9
- moveq #0,d0
- rts
- L9: moveq #1,d0
- rts
- }
-
- /************************************************************************/
- /* Purpose..: Test if two pointers to function member are equal */
- /* Input....: two pointers to function members */
- /* Return...: 1: *ptmf1!=*ptmf2; 0: *ptmf1==*ptmf2 */
- /************************************************************************/
- asm long __ptmf_cmpr(const PTMF *ptmf1,const PTMF *ptmf2)
- {
- move.l 4(sp),a0 // *ptmf1
- move.l 8(sp),a1 // *ptmf2
- cmpm.l (a0)+,(a1)+
- bne.s L9
- cmpm.l (a0)+,(a1)+
- bne.s L9
- cmpm.l (a0)+,(a1)+
- bne.s L9
- moveq #0,d0
- rts
- L9: moveq #1,d0
- rts
- }
-
- /************************************************************************/
- /* Purpose..: Call a member function through a pointer to member */
- /* Input....: (a0: pointer to this if THIS_IN_A0!=0) */
- /* Input....: (a1: pointer to pointer to function member struct) */
- /* Input....: (all other arguments on stack) */
- /* Return...: --- */
- /************************************************************************/
- asm void __ptmf_call(...)
- {
- #if !THIS_IN_A0
- move.l 4(sp),a0 // load this pointer into a0
- add.l struct(PTMF.this_delta)(a1),a0 // adjust this pointer
- move.l a0,4(sp) // store new this pointer
- #else
- add.l struct(PTMF.this_delta)(a1),a0 // adjust this pointer
- #endif
- tst.l struct(PTMF.vtbl_offset)(a1)
- blt.s directcall
-
- move.l struct(PTMF.vtbl_offset)(a1),-(sp)
- move.l struct(PTMF.func_data.ventry_offset)(a1),-(sp)
- move.l a0,a1 // load *this to a1
- add.l (sp)+,a1 // add offset of vtableptr to a1
- move.l (a1),a1 // load vtableptr to a1
- add.l (sp)+,a1 // add vtable entry offset to a1
- add.l 4(a1),a0 // adjust adjust this pointer by vtable entry offset delta
- #if !THIS_IN_A0
- move.l a0,4(sp) // store new this pointer
- #endif
- move.l (a1),a1 // get function address from vtable entry
- jmp (a1)
-
- directcall:
- move.l struct(PTMF.func_data.func_addr)(a1),a1
- jmp (a1)
- }
-
- /************************************************************************/
- /* Purpose..: Call a member function through a pointer to member */
- /* Input....: (a0: pointer to this if THIS_IN_A0!=0) */
- /* Input....: (a1: pointer to pointer to function member struct) */
- /* Input....: (all other arguments on stack) */
- /* Return...: --- */
- /************************************************************************/
- asm void __ptmf_scall(...)
- {
- tst.l struct(PTMF.vtbl_offset)(a1)
- blt.s directcall
-
- move.l struct(PTMF.vtbl_offset)(a1),-(sp)
- move.l struct(PTMF.func_data.ventry_offset)(a1),-(sp)
- #if !THIS_IN_A0
- move.l a0,a1 // load this pointer into a1
- #else
- move.l 4+8(sp),a1 // load this pointer into a1
- #endif
- add.l (sp)+,a1 // add offset of vtableptr to a1
- move.l (a1),a1 // load vtableptr to a1
- add.l (sp)+,a1 // add vtable entry offset to a1
- move.l (a1),a1 // get function address from vtable entry
- jmp (a1)
-
- directcall:
- move.l struct(PTMF.func_data.func_addr)(a1),a1
- jmp (a1)
- }
-
- /************************************************************************/
- /* Purpose..: This function will copy/cast a pointer to func member */
- /* Input....: offset delta to apply to pointer to function member */
- /* Input....: pointer to original pointer to function member */
- /* Input....: pointer to destiniation pointer to function member */
- /* Return...: pointer to destiniation pointer to function member */
- /************************************************************************/
- PTMF *__ptmf_cast(long offset,const PTMF *ptmfrom,PTMF *ptmto)
- {
- ptmto->this_delta=ptmfrom->this_delta+offset;
-
- if(((PTMF *)ptmfrom)->vtbl_offset>=0L)
- { // virtual function pointer
- ((PTMF *)ptmto)->vtbl_offset=((PTMF *)ptmfrom)->vtbl_offset+offset;
- ((PTMF *)ptmto)->func_data.ventry_offset=((PTMF *)ptmfrom)->func_data.ventry_offset;
- }
- else
- { // nonvirtual function pointer
- ((PTMF *)ptmto)->vtbl_offset=-1L;
- ((PTMF *)ptmto)->func_data.func_addr=((PTMF *)ptmfrom)->func_data.func_addr;
- }
- return(ptmto);
- }
-
- /************************************************************************/
- /* Purpose..: Copy data */
- /* Input....: pointer to destination (can be 0L: no copy) */
- /* Input....: pointer to source */
- /* Input....: number of bytes to copy */
- /* Return...: pointer to destination (or 0L) */
- /************************************************************************/
- void *__copy(char *to,char *from,size_t size)
- {
- char *f,*t;
-
- if(to) for(f=(char *)from,t=(char *)to; size>0; size--) *t++=*f++;
- return to;
- }
-
- /************************************************************************/
- /* Purpose..: Initialize an array of objects */
- /* Input....: pointer to allocated memory (+8 bytes) (0L: error) */
- /* Input....: pointer to default constructor function (if any) */
- /* Input....: size of one object */
- /* Input....: number of objects */
- /* Return...: pointer to first object */
- /************************************************************************/
- void *__init_arr(void *memptr,ConstructorDestructor constructor,size_t object_size,size_t nobjects)
- {
- char *ptr;
-
- // Theory of operation:
- //
- // Allocate space for: two size_t objects and nobjects*object_size objects;
- // Store number of allocated object and size of one object at the beginnig of the allocated block;
- // Call constructor (if any) to initialize object memory;
- // return pointer to first object;
-
- if((ptr=(char *)memptr)!=0L)
- {
- *(size_t *)ptr=object_size;
- *(size_t *)(ptr+sizeof(size_t))=nobjects;
- ptr+=sizeof(size_t)*2;
-
- if(constructor)
- {
- char *p;
- size_t i;
-
- for(i=0,p=ptr; i<nobjects; i++,p+=object_size) constructor(p,1);
- }
- }
- return(ptr);
- }
-
- /************************************************************************/
- /* Purpose..: Construct an array of objects */
- /* Input....: pointer to default constructor function (if any) */
- /* Input....: size of one object */
- /* Input....: number of objects */
- /* Return...: pointer to first object */
- /************************************************************************/
- void *__new_arr(ConstructorDestructor constructor,size_t object_size,size_t nobjects)
- {
- char *ptr;
-
- // Theory of operation:
- //
- // Allocate space for: two size_t objects and nobjects*object_size objects;
- // Store number of allocated object and size of one object at the begining of the allocated block;
- // Call constructor (if any) to initialize object memory;
- // return pointer to first object;
-
- if((ptr=(char *)::operator new(2*sizeof(size_t)+object_size*nobjects))!=0L)
- {
- *(size_t *)ptr=object_size;
- *(size_t *)(ptr+sizeof(size_t))=nobjects;
- ptr+=sizeof(size_t)*2;
- if(constructor)
- {
- char *p;
- size_t i;
-
- for(i=0,p=ptr; i<nobjects; i++,p+=object_size) constructor(p,1);
- }
- }
- return(ptr);
- }
-
- /************************************************************************/
- /* Purpose..: Delete an array of objects */
- /* Input....: pointer to first object (can be 0L) */
- /* Input....: pointer to destructor function (if any) */
- /* Return...: --- */
- /************************************************************************/
- void __del_arr(void *memptr,ConstructorDestructor destructor)
- {
- if(memptr)
- {
- if(destructor)
- {
- size_t i,objects,objectsize;
- char *p;
-
- objectsize=*(size_t *)((char *)memptr-2*sizeof(size_t));
- objects=*(size_t *)((char *)memptr-sizeof(size_t));
- p=(char *)memptr+objectsize*objects;
- for(i=0; i<objects; i++)
- {
- p-=objectsize; destructor(p,-1);
- }
- }
- ::delete ((char *)memptr-2*sizeof(size_t));
- }
- }
-
- /************************************************************************/
- /* Purpose..: Construct/destruct an array of objects */
- /* Input....: pointer to memory location */
- /* Input....: pointer to constructor/destructor function */
- /* Input....: size of object */
- /* Input....: number of objects */
- /* Return...: --- */
- /************************************************************************/
- void __dc_arr(void *mem,ConstructorDestructor con_des,short object_size,short objects)
- {
- while(objects-->0) { con_des(mem,-1); *((char **)&mem)+=object_size; }
- }
-